{
 "cells": [
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# N-Step Deep Q Network"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Imports"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 1,
   "metadata": {},
   "outputs": [],
   "source": [
    "import gym\n",
    "import numpy as np\n",
    "import torch\n",
    "import torch.optim as optim\n",
    "\n",
    "from IPython.display import clear_output\n",
    "from matplotlib import pyplot as plt\n",
    "%matplotlib inline\n",
    "\n",
    "from timeit import default_timer as timer\n",
    "from datetime import timedelta\n",
    "import math\n",
    "\n",
    "from utils.wrappers import *\n",
    "from networks.networks import DQN\n",
    "from networks.network_bodies import AtariBody\n",
    "from utils.ReplayMemory import ExperienceReplayMemory\n",
    "\n",
    "from utils.hyperparameters import Config\n",
    "from agents.BaseAgent import BaseAgent"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Hyperparameters"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 2,
   "metadata": {},
   "outputs": [],
   "source": [
    "config = Config()\n",
    "\n",
    "config.device = torch.device(\"cuda\" if torch.cuda.is_available() else \"cpu\")\n",
    "\n",
    "#epsilon variables\n",
    "config.epsilon_start = 1.0\n",
    "config.epsilon_final = 0.01\n",
    "config.epsilon_decay = 30000\n",
    "config.epsilon_by_frame = lambda frame_idx: config.epsilon_final + (config.epsilon_start - config.epsilon_final) * math.exp(-1. * frame_idx / config.epsilon_decay)\n",
    "\n",
    "#misc agent variables\n",
    "config.GAMMA=0.99\n",
    "config.LR=1e-4\n",
    "\n",
    "#memory\n",
    "config.TARGET_NET_UPDATE_FREQ = 1000\n",
    "config.EXP_REPLAY_SIZE = 100000\n",
    "config.BATCH_SIZE = 32\n",
    "\n",
    "#Learning control variables\n",
    "config.LEARN_START = 10000\n",
    "config.MAX_FRAMES=1000000\n",
    "\n",
    "#Nstep controls\n",
    "config.N_STEPS=3"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Agent"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 3,
   "metadata": {},
   "outputs": [],
   "source": [
    "class Model(BaseAgent):\n",
    "    def __init__(self, static_policy=False, env=None, config=None):\n",
    "        super(Model, self).__init__()\n",
    "        self.device = config.device\n",
    "\n",
    "        self.gamma = config.GAMMA\n",
    "        self.lr = config.LR\n",
    "        self.target_net_update_freq = config.TARGET_NET_UPDATE_FREQ\n",
    "        self.experience_replay_size = config.EXP_REPLAY_SIZE\n",
    "        self.batch_size = config.BATCH_SIZE\n",
    "        self.learn_start = config.LEARN_START\n",
    "        self.sigma_init= config.SIGMA_INIT\n",
    "        self.priority_beta_start = config.PRIORITY_BETA_START\n",
    "        self.priority_beta_frames = config.PRIORITY_BETA_FRAMES\n",
    "        self.priority_alpha = config.PRIORITY_ALPHA\n",
    "\n",
    "        self.static_policy = static_policy\n",
    "        self.num_feats = env.observation_space.shape\n",
    "        self.num_actions = env.action_space.n\n",
    "        self.env = env\n",
    "\n",
    "        self.declare_networks()\n",
    "            \n",
    "        self.target_model.load_state_dict(self.model.state_dict())\n",
    "        self.optimizer = optim.Adam(self.model.parameters(), lr=self.lr)\n",
    "        \n",
    "        #move to correct device\n",
    "        self.model = self.model.to(self.device)\n",
    "        self.target_model.to(self.device)\n",
    "\n",
    "        if self.static_policy:\n",
    "            self.model.eval()\n",
    "            self.target_model.eval()\n",
    "        else:\n",
    "            self.model.train()\n",
    "            self.target_model.train()\n",
    "\n",
    "        self.update_count = 0\n",
    "\n",
    "        self.declare_memory()\n",
    "\n",
    "        self.nsteps = config.N_STEPS\n",
    "        self.nstep_buffer = []\n",
    "\n",
    "    def declare_networks(self):\n",
    "        self.model = DQN(self.num_feats, self.num_actions, body=AtariBody)\n",
    "        self.target_model = DQN(self.num_feats, self.num_actions, body=AtariBody)\n",
    "\n",
    "    def declare_memory(self):\n",
    "        self.memory = ExperienceReplayMemory(self.experience_replay_size)\n",
    "\n",
    "    def append_to_replay(self, s, a, r, s_):\n",
    "        self.nstep_buffer.append((s, a, r, s_))\n",
    "\n",
    "        if(len(self.nstep_buffer)<self.nsteps):\n",
    "            return\n",
    "        \n",
    "        R = sum([self.nstep_buffer[i][2]*(self.gamma**i) for i in range(self.nsteps)])\n",
    "        state, action, _, _ = self.nstep_buffer.pop(0)\n",
    "\n",
    "        self.memory.push((state, action, R, s_))\n",
    "\n",
    "    def prep_minibatch(self):\n",
    "        # random transition batch is taken from experience replay memory\n",
    "        transitions, indices, weights = self.memory.sample(self.batch_size)\n",
    "        \n",
    "        batch_state, batch_action, batch_reward, batch_next_state = zip(*transitions)\n",
    "\n",
    "        shape = (-1,)+self.num_feats\n",
    "\n",
    "        batch_state = torch.tensor(batch_state, device=self.device, dtype=torch.float).view(shape)\n",
    "        batch_action = torch.tensor(batch_action, device=self.device, dtype=torch.long).squeeze().view(-1, 1)\n",
    "        batch_reward = torch.tensor(batch_reward, device=self.device, dtype=torch.float).squeeze().view(-1, 1)\n",
    "        \n",
    "        non_final_mask = torch.tensor(tuple(map(lambda s: s is not None, batch_next_state)), device=self.device, dtype=torch.uint8)\n",
    "        try: #sometimes all next states are false\n",
    "            non_final_next_states = torch.tensor([s for s in batch_next_state if s is not None], device=self.device, dtype=torch.float).view(shape)\n",
    "            empty_next_state_values = False\n",
    "        except:\n",
    "            non_final_next_states = None\n",
    "            empty_next_state_values = True\n",
    "\n",
    "        return batch_state, batch_action, batch_reward, non_final_next_states, non_final_mask, empty_next_state_values, indices, weights\n",
    "\n",
    "    def compute_loss(self, batch_vars):\n",
    "        batch_state, batch_action, batch_reward, non_final_next_states, non_final_mask, empty_next_state_values, indices, weights = batch_vars\n",
    "\n",
    "        #estimate\n",
    "        self.model.sample_noise()\n",
    "        current_q_values = self.model(batch_state).gather(1, batch_action)\n",
    "        \n",
    "        #target\n",
    "        with torch.no_grad():\n",
    "            max_next_q_values = torch.zeros(self.batch_size, device=self.device, dtype=torch.float).unsqueeze(dim=1)\n",
    "            if not empty_next_state_values:\n",
    "                max_next_action = self.get_max_next_state_action(non_final_next_states)\n",
    "                self.target_model.sample_noise()\n",
    "                max_next_q_values[non_final_mask] = self.target_model(non_final_next_states).gather(1, max_next_action)\n",
    "            expected_q_values = batch_reward + ((self.gamma**self.nsteps)*max_next_q_values)\n",
    "\n",
    "        diff = (expected_q_values - current_q_values)\n",
    "        loss = self.huber(diff)\n",
    "        loss = loss.mean()\n",
    "\n",
    "        return loss\n",
    "\n",
    "    def update(self, s, a, r, s_, frame=0):\n",
    "        if self.static_policy:\n",
    "            return None\n",
    "\n",
    "        self.append_to_replay(s, a, r, s_)\n",
    "\n",
    "        if frame < self.learn_start:\n",
    "            return None\n",
    "\n",
    "        batch_vars = self.prep_minibatch()\n",
    "\n",
    "        loss = self.compute_loss(batch_vars)\n",
    "\n",
    "        # Optimize the model\n",
    "        self.optimizer.zero_grad()\n",
    "        loss.backward()\n",
    "        for param in self.model.parameters():\n",
    "            param.grad.data.clamp_(-1, 1)\n",
    "        self.optimizer.step()\n",
    "\n",
    "        self.update_target_model()\n",
    "        self.save_loss(loss.item())\n",
    "        self.save_sigma_param_magnitudes()\n",
    "\n",
    "    def get_action(self, s, eps=0.1):\n",
    "        with torch.no_grad():\n",
    "            if np.random.random() >= eps or self.static_policy:\n",
    "                X = torch.tensor([s], device=self.device, dtype=torch.float)\n",
    "                a = self.model(X).max(1)[1].view(1, 1)\n",
    "                return a.item()\n",
    "            else:\n",
    "                return np.random.randint(0, self.num_actions)\n",
    "\n",
    "    def update_target_model(self):\n",
    "        self.update_count+=1\n",
    "        self.update_count = self.update_count % self.target_net_update_freq\n",
    "        if self.update_count == 0:\n",
    "            self.target_model.load_state_dict(self.model.state_dict())\n",
    "\n",
    "    def get_max_next_state_action(self, next_states):\n",
    "        return self.target_model(next_states).max(dim=1)[1].view(-1, 1)\n",
    "\n",
    "    def finish_nstep(self):\n",
    "        while len(self.nstep_buffer) > 0:\n",
    "            R = sum([self.nstep_buffer[i][2]*(self.gamma**i) for i in range(len(self.nstep_buffer))])\n",
    "            state, action, _, _ = self.nstep_buffer.pop(0)\n",
    "\n",
    "            self.memory.push((state, action, R, None))\n",
    "\n",
    "    def huber(self, x):\n",
    "        cond = (x.abs() < 1.0).float().detach()\n",
    "        return 0.5 * x.pow(2) * cond + (x.abs() - 0.5) * (1.0 - cond)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Plot Results"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 4,
   "metadata": {},
   "outputs": [],
   "source": [
    "def plot(frame_idx, rewards, losses, sigma, elapsed_time):\n",
    "    clear_output(True)\n",
    "    plt.figure(figsize=(20,5))\n",
    "    plt.subplot(131)\n",
    "    plt.title('frame %s. reward: %s. time: %s' % (frame_idx, np.mean(rewards[-10:]), elapsed_time))\n",
    "    plt.plot(rewards)\n",
    "    if losses:\n",
    "        plt.subplot(132)\n",
    "        plt.title('loss')\n",
    "        plt.plot(losses)\n",
    "    if sigma:\n",
    "        plt.subplot(133)\n",
    "        plt.title('noisy param magnitude')\n",
    "        plt.plot(sigma)\n",
    "    plt.show()"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Training Loop"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 5,
   "metadata": {
    "scrolled": true
   },
   "outputs": [
    {
     "data": {
      "image/png": "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\n",
      "text/plain": [
       "<Figure size 1440x360 with 2 Axes>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "start=timer()\n",
    "\n",
    "env_id = \"PongNoFrameskip-v4\"\n",
    "env    = make_atari(env_id)\n",
    "env    = wrap_deepmind(env, frame_stack=False)\n",
    "env    = wrap_pytorch(env)\n",
    "#env = gym.make('CartPole-v0')\n",
    "#env = wrappers.Monitor(env, 'Delete', force=True)\n",
    "model = Model(env=env, config=config)\n",
    "\n",
    "episode_reward = 0\n",
    "\n",
    "observation = env.reset()\n",
    "for frame_idx in range(1, config.MAX_FRAMES + 1):\n",
    "    epsilon = config.epsilon_by_frame(frame_idx)\n",
    "\n",
    "    action = model.get_action(observation, epsilon)\n",
    "    prev_observation=observation\n",
    "    observation, reward, done, _ = env.step(action)\n",
    "    observation = None if done else observation\n",
    "\n",
    "    model.update(prev_observation, action, reward, observation, frame_idx)\n",
    "    episode_reward += reward\n",
    "\n",
    "    if done:\n",
    "        model.finish_nstep()\n",
    "        observation = env.reset()\n",
    "        model.save_reward(episode_reward)\n",
    "        episode_reward = 0\n",
    "        \n",
    "        if np.mean(model.rewards[-10:]) > 19:\n",
    "            plot(frame_idx, model.rewards, model.losses, model.sigma_parameter_mag, timedelta(seconds=int(timer()-start)))\n",
    "            break\n",
    "\n",
    "    if frame_idx % 10000 == 0:\n",
    "        plot(frame_idx, model.rewards, model.losses, model.sigma_parameter_mag, timedelta(seconds=int(timer()-start)))\n",
    "\n",
    "model.save_w()\n",
    "env.close()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": []
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.6.5"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 2
}
